﻿namespace UnityEditor
{
    using NUnit.Framework;
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;
    using UnityEngine;

    internal abstract class ModuleUI : SerializedModule
    {
        protected static float k_Column1;
        protected static float k_Column2;
        public static float k_CompactFixedModuleWidth = 195f;
        protected static float k_ContentColumn2;
        public static float k_ContentLeftMargin = 3f;
        public static float k_ContentRightMargin = 3f;
        protected const float k_minMaxToggleWidth = 8f;
        public static float k_ModuleWidth;
        public static float k_SpaceBetweenModules = 5f;
        protected const float k_toggleAdjustToCenter = 2f;
        protected const float k_toggleWidth = 12f;
        protected const float kColorSpace = 32f;
        protected const float kCurveSpace = 35f;
        protected const int kMaxPart = 0;
        protected const float kMinCurveColor = 0.75f;
        protected const int kMinPart = 1;
        protected static readonly Rect kSignedRange = new Rect(0f, -1f, 1f, 2f);
        protected static readonly Rect kUnsignedRange = new Rect(0f, 0f, 1f, 1f);
        protected static readonly bool kUseSignedRange = true;
        private List<SerializedProperty> m_CurvesRemovedWhenFolded;
        private string m_DisplayName;
        private SerializedProperty m_Enabled;
        public List<SerializedProperty> m_ModuleCurves;
        public ParticleSystemUI m_ParticleSystemUI;
        protected string m_ToolTip;
        private VisibilityState m_VisibilityState;

        public ModuleUI(ParticleSystemUI owner, SerializedObject o, string name, string displayName) : base(o, name)
        {
            this.m_ToolTip = string.Empty;
            this.m_ModuleCurves = new List<SerializedProperty>();
            this.m_CurvesRemovedWhenFolded = new List<SerializedProperty>();
            this.Setup(owner, o, name, displayName, VisibilityState.NotVisible);
        }

        public ModuleUI(ParticleSystemUI owner, SerializedObject o, string name, string displayName, VisibilityState initialVisibilityState) : base(o, name)
        {
            this.m_ToolTip = string.Empty;
            this.m_ModuleCurves = new List<SerializedProperty>();
            this.m_CurvesRemovedWhenFolded = new List<SerializedProperty>();
            this.Setup(owner, o, name, displayName, initialVisibilityState);
        }

        public void AddToModuleCurves(SerializedProperty curveProp)
        {
            this.m_ModuleCurves.Add(curveProp);
            if (!this.foldout)
            {
                this.m_CurvesRemovedWhenFolded.Add(curveProp);
            }
        }

        internal void CheckVisibilityState()
        {
            if ((!(this is RendererModuleUI) && !this.m_Enabled.boolValue) && !ParticleEffectUI.GetAllModulesVisible())
            {
                this.SetVisibilityState(VisibilityState.NotVisible);
            }
            if (this.m_Enabled.boolValue && !this.visibleUI)
            {
                this.SetVisibilityState(VisibilityState.VisibleAndFolded);
            }
        }

        private static float FloatDraggable(Rect rect, SerializedProperty floatProp, float remap, float dragWidth, float floatFieldWidth)
        {
            return FloatDraggable(rect, floatProp, remap, dragWidth, floatFieldWidth, "g7");
        }

        public static float FloatDraggable(Rect rect, float floatValue, float remap, float dragWidth, float floatFieldWidth, string formatString)
        {
            int id = EditorGUI.GetControlID(0x62dd15e9, FocusType.Keyboard, rect);
            Rect dragHotZone = rect;
            dragHotZone.width = dragWidth;
            Rect position = rect;
            position.x += dragWidth;
            position.width = floatFieldWidth;
            return (EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, position, dragHotZone, id, floatValue * remap, formatString, ParticleSystemStyles.Get().numberField, true) / remap);
        }

        public static float FloatDraggable(Rect rect, SerializedProperty floatProp, float remap, float dragWidth, float floatFieldWidth, string formatString)
        {
            float floatValue = floatProp.floatValue;
            float num2 = FloatDraggable(rect, floatValue, remap, dragWidth, floatFieldWidth, formatString);
            if (num2 != floatValue)
            {
                floatProp.floatValue = num2;
            }
            return num2;
        }

        private static Color GetColor(SerializedMinMaxCurve mmCurve)
        {
            return mmCurve.m_Module.m_ParticleSystemUI.m_ParticleEffectUI.GetParticleSystemCurveEditor().GetCurveColor(mmCurve.maxCurve);
        }

        protected ParticleSystem GetParticleSystem()
        {
            return (this.m_Enabled.serializedObject.targetObject as ParticleSystem);
        }

        public ParticleSystemCurveEditor GetParticleSystemCurveEditor()
        {
            return this.m_ParticleSystemUI.m_ParticleEffectUI.GetParticleSystemCurveEditor();
        }

        public virtual float GetXAxisScalar()
        {
            return 1f;
        }

        public static bool GUIBoolAsPopup(GUIContent label, SerializedProperty boolProp, string[] options)
        {
            Assert.That(options.Length == 2);
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            rect.x += k_Column1;
            rect.width = k_ContentColumn2;
            int selectedIndex = !boolProp.boolValue ? 0 : 1;
            int num2 = EditorGUI.Popup(rect, selectedIndex, options, ParticleSystemStyles.Get().popup);
            if (num2 != selectedIndex)
            {
                boolProp.boolValue = num2 > 0;
            }
            return (num2 > 0);
        }

        private static void GUIColor(Rect rect, SerializedProperty colorProp)
        {
            colorProp.colorValue = EditorGUI.ColorField(rect, colorProp.colorValue, false, true);
        }

        private static void GUICurveField(Rect position, SerializedProperty maxCurve, SerializedProperty minCurve, Color color, Rect ranges, CurveFieldMouseDownCallback mouseDownCallback)
        {
            int controlID = EditorGUI.GetControlID(0x4ec1c30f, EditorGUIUtility.native, position);
            Event current = Event.current;
            switch (current.GetTypeForControl(controlID))
            {
                case EventType.MouseDown:
                    if ((position.Contains(current.mousePosition) && (mouseDownCallback != null)) && mouseDownCallback(current.button, position, ranges))
                    {
                        current.Use();
                    }
                    break;

                case EventType.Repaint:
                {
                    Rect rect = position;
                    rect.y++;
                    rect.height--;
                    if (minCurve == null)
                    {
                        EditorGUIUtility.DrawCurveSwatch(rect, null, maxCurve, color, EditorGUI.kCurveBGColor, ranges);
                    }
                    else
                    {
                        EditorGUIUtility.DrawRegionSwatch(rect, maxCurve, minCurve, color, EditorGUI.kCurveBGColor, ranges);
                    }
                    break;
                }
            }
        }

        public static float GUIFloat(string label, SerializedProperty floatProp)
        {
            return GUIFloat(GUIContent.Temp(label), floatProp);
        }

        public static float GUIFloat(GUIContent guiContent, SerializedProperty floatProp)
        {
            return GUIFloat(guiContent, floatProp, "g7");
        }

        public static float GUIFloat(GUIContent guiContent, float floatValue, string formatString)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            return FloatDraggable(rect, floatValue, 1f, k_Column1, k_ContentColumn2, formatString);
        }

        public static float GUIFloat(GUIContent guiContent, SerializedProperty floatProp, string formatString)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            return FloatDraggable(rect, floatProp, 1f, k_Column1, k_ContentColumn2, formatString);
        }

        public static void GUIFloatAndCurve(GUIContent label, SerializedProperty floatProp, SerializedProperty curveProp, Color curveColor, CurveFieldMouseDownCallback mouseDownCallback)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            float num = 10f;
            float floatFieldWidth = 30f;
            float width = (k_ContentColumn2 - floatFieldWidth) - num;
            FloatDraggable(rect, floatProp, 1f, k_Column1, floatFieldWidth);
            Rect position = new Rect(((rect.x + k_Column1) + floatFieldWidth) + num, rect.y, width, 14f);
            GUICurveField(position, curveProp, null, curveColor, kUnsignedRange, mouseDownCallback);
        }

        private static void GUIGradientAsColor(Rect rect, SerializedProperty gradientProp)
        {
            bool changed = GUI.changed;
            GUI.changed = false;
            Color gradientAsColor = SerializedMinMaxGradient.GetGradientAsColor(gradientProp);
            gradientAsColor = EditorGUI.ColorField(rect, gradientAsColor, false, true);
            if (GUI.changed)
            {
                SerializedMinMaxGradient.SetGradientAsColor(gradientProp, gradientAsColor);
            }
            GUI.changed |= changed;
        }

        public static int GUIInt(GUIContent guiContent, int intValue)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            return IntDraggable(rect, null, intValue, k_Column1, k_Column2);
        }

        public static void GUIInt(GUIContent guiContent, SerializedProperty intProp)
        {
            intProp.intValue = GUIInt(guiContent, intProp.intValue);
        }

        public static int GUIIntDraggable(GUIContent label, int intValue)
        {
            return IntDraggable(GUILayoutUtility.GetRect(k_ModuleWidth, 16f), label, intValue, k_Column1, k_Column2);
        }

        public static int GUIIntDraggable(GUIContent label, SerializedProperty intProp)
        {
            return GUIIntDraggable(label, intProp.intValue);
        }

        public static void GUIIntDraggableX2(GUIContent mainLabel, GUIContent label1, SerializedProperty intProp1, GUIContent label2, SerializedProperty intProp2)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, mainLabel);
            float num = 10f;
            float width = (k_Column2 - num) * 0.5f;
            float dragWidth = width * 0.35f;
            float intFieldWidth = width * 0.65f;
            Rect rect2 = new Rect(rect.x + k_Column1, rect.y, width, rect.height);
            IntDraggable(rect2, label1, intProp1, dragWidth, intFieldWidth);
            rect2.x += width + num;
            IntDraggable(rect2, label2, intProp2, dragWidth, intFieldWidth);
        }

        public void GUILabel(string label)
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(97f) };
            GUILayout.Label(label, options);
        }

        public static void GUILayerMask(GUIContent guiContent, SerializedProperty boolProp)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            Rect position = new Rect(rect.x + k_Column1, rect.y + 2f, k_ContentColumn2, 12f);
            EditorGUI.LayerMaskField(position, boolProp, GUIContent.none, ParticleSystemStyles.Get().popup);
            SpaceToNextLine();
        }

        public int GUIListOfFloatObjectToggleFields(GUIContent label, SerializedProperty[] floatProps, SerializedProperty[] objectProps, EditorGUI.ObjectFieldValidator validator, GUIContent buttonTooltip, bool allowCreation)
        {
            int num = -1;
            int length = objectProps.Length;
            int num3 = (floatProps == null) ? 0 : 1;
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f * (length + num3));
            float dragWidth = 10f;
            float floatFieldWidth = 35f;
            float num6 = 10f;
            float width = (((k_ModuleWidth - dragWidth) - floatFieldWidth) - (num6 * 2f)) - 12f;
            Rect rect2 = rect;
            rect2.height = 16f;
            PrefixLabel(rect2, label);
            if (floatProps != null)
            {
                rect2.y += 16f;
            }
            for (int i = 0; i < length; i++)
            {
                SerializedProperty property = objectProps[i];
                SerializedProperty floatProp = null;
                if (floatProps != null)
                {
                    floatProp = floatProps[i];
                }
                Rect rect3 = rect2;
                if (floatProp != null)
                {
                    float num9 = FloatDraggable(rect3, floatProp, 1f, dragWidth, floatFieldWidth);
                    if ((num9 < 0f) || (num9 > 1f))
                    {
                        floatProp.floatValue = Mathf.Clamp01(num9);
                    }
                }
                rect3 = new Rect(((rect2.x + dragWidth) + floatFieldWidth) + num6, rect2.y + 2f, width, rect2.height);
                int id = EditorGUI.GetControlID(0x12da2a, EditorGUIUtility.native, rect3);
                EditorGUI.DoObjectField(rect3, rect3, id, null, null, property, validator, true, ParticleSystemStyles.Get().objectField);
                if (property.objectReferenceValue == null)
                {
                    rect3 = new Rect((rect2.x + k_ModuleWidth) - 12f, rect2.y + 5f, 12f, 12f);
                    if (allowCreation)
                    {
                        if (buttonTooltip == null)
                        {
                        }
                        if (!GUI.Button(rect3, GUIContent.none, ParticleSystemStyles.Get().plus))
                        {
                            goto Label_01BA;
                        }
                    }
                    num = i;
                }
            Label_01BA:
                rect2.y += 16f;
            }
            return num;
        }

        public void GUIMinMaxColor(GUIContent label, SerializedMinMaxColor minMaxColor)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            float width = (k_Column2 - 8f) - 5f;
            if (!minMaxColor.minMax.boolValue)
            {
                Rect rect2 = new Rect(rect.x + k_Column1, rect.y, width, rect.height - 2f);
                GUIColor(rect2, minMaxColor.maxColor);
            }
            else
            {
                Rect rect3 = new Rect(rect.x + k_Column1, rect.y, (width * 0.5f) - 2f, rect.height - 2f);
                GUIColor(rect3, minMaxColor.minColor);
                rect3.x += rect3.width + 4f;
                GUIColor(rect3, minMaxColor.maxColor);
            }
            Rect rect4 = new Rect((rect.x + k_ModuleWidth) - 8f, rect.y, 8f, 8f);
            GUIMMColorPopUp(rect4, minMaxColor.minMax);
        }

        public static void GUIMinMaxCurve(string label, SerializedMinMaxCurve mmCurve)
        {
            GUIMinMaxCurve(GUIContent.Temp(label), mmCurve);
        }

        public static void GUIMinMaxCurve(GUIContent label, SerializedMinMaxCurve mmCurve)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            float dragWidth = k_Column1;
            float floatFieldWidth = (k_ContentColumn2 - 4f) - 8f;
            MinMaxCurveState state = mmCurve.state;
            rect.width = k_Column1;
            PrefixLabel(rect, label);
            switch (state)
            {
                case MinMaxCurveState.k_Scalar:
                {
                    float a = FloatDraggable(rect, mmCurve.scalar, mmCurve.m_RemapValue, dragWidth, floatFieldWidth);
                    if (!mmCurve.signedRange)
                    {
                        mmCurve.scalar.floatValue = Mathf.Max(a, 0f);
                    }
                    break;
                }
                case MinMaxCurveState.k_TwoScalars:
                {
                    float num4 = floatFieldWidth * 0.2f;
                    float num5 = (floatFieldWidth - num4) * 0.5f;
                    float minConstant = mmCurve.minConstant;
                    float maxConstant = mmCurve.maxConstant;
                    EditorGUI.BeginChangeCheck();
                    minConstant = FloatDraggable(rect, minConstant, mmCurve.m_RemapValue, dragWidth, num5, "g5");
                    if (EditorGUI.EndChangeCheck())
                    {
                        mmCurve.minConstant = minConstant;
                    }
                    Rect rect2 = rect;
                    rect2.x += k_Column1 + num5;
                    rect2.width = num5;
                    EditorGUI.BeginChangeCheck();
                    maxConstant = FloatDraggable(rect2, maxConstant, mmCurve.m_RemapValue, num4, num5, "g5");
                    if (EditorGUI.EndChangeCheck())
                    {
                        mmCurve.maxConstant = maxConstant;
                    }
                    break;
                }
                default:
                {
                    Rect position = rect;
                    position.x += k_Column1;
                    position.height = 13f;
                    position.width = floatFieldWidth;
                    Rect ranges = !mmCurve.signedRange ? kUnsignedRange : kSignedRange;
                    SerializedProperty minCurve = (state != MinMaxCurveState.k_TwoCurves) ? null : mmCurve.minCurve;
                    GUICurveField(position, mmCurve.maxCurve, minCurve, GetColor(mmCurve), ranges, new CurveFieldMouseDownCallback(mmCurve.OnCurveAreaMouseDown));
                    break;
                }
            }
            Rect rect5 = new Rect(((rect.x + k_ModuleWidth) - 8f) - k_ContentRightMargin, rect.y, 8f, rect.height);
            GUIMMCurveStateList(rect5, mmCurve);
            SpaceToNextLine();
        }

        public void GUIMinMaxGradient(GUIContent label, SerializedMinMaxGradient minMaxGradient)
        {
            float height = 13f;
            float width = (k_ContentColumn2 - 4f) - 8f;
            MinMaxGradientState state = minMaxGradient.state;
            bool flag = state >= MinMaxGradientState.k_RandomBetweenTwoColors;
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, !flag ? 16f : ((2f * height) + 2f));
            Rect rect2 = new Rect(rect.x, rect.y, k_Column1, 16f);
            PrefixLabel(rect2, label);
            Rect rect3 = new Rect(rect.x + k_Column1, rect.y, width, height);
            switch (state)
            {
                case MinMaxGradientState.k_Color:
                    GUIColor(rect3, minMaxGradient.m_MaxColor);
                    break;

                case MinMaxGradientState.k_Gradient:
                    EditorGUI.GradientField(rect3, minMaxGradient.m_MaxGradient);
                    break;

                case MinMaxGradientState.k_RandomBetweenTwoColors:
                    GUIColor(rect3, minMaxGradient.m_MaxColor);
                    rect3.y += rect3.height - 1f;
                    GUIColor(rect3, minMaxGradient.m_MinColor);
                    break;

                case MinMaxGradientState.k_RandomBetweenTwoGradients:
                    EditorGUI.GradientField(rect3, minMaxGradient.m_MaxGradient);
                    rect3.y += rect3.height - 1f;
                    EditorGUI.GradientField(rect3, minMaxGradient.m_MinGradient);
                    break;
            }
            Rect rect4 = new Rect(rect3.x + rect3.width, rect.y, ((k_ModuleWidth - k_Column1) - width) - k_ContentRightMargin, rect.height);
            GUIMMGradientPopUp(rect4, minMaxGradient);
        }

        public static void GUIMinMaxRange(GUIContent label, SerializedProperty vec2Prop)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            rect.height = 16f;
            PrefixLabel(rect, label);
            float dragWidth = 14f;
            float floatFieldWidth = (k_ContentColumn2 - dragWidth) * 0.5f;
            Vector2 vector = vec2Prop.vector2Value;
            Rect rect2 = rect;
            rect2.width = floatFieldWidth;
            vector.x = FloatDraggable(rect2, vector.x, 1f, k_Column1, floatFieldWidth, "g7");
            vector.x = Mathf.Clamp(vector.x, 0f, vector.y - 0.01f);
            rect2.x += k_Column1 + floatFieldWidth;
            vector.y = FloatDraggable(rect2, vector.y, 1f, dragWidth, floatFieldWidth, "g7");
            vector.y = Mathf.Max(vector.x + 0.01f, vector.y);
            vec2Prop.vector2Value = vector;
        }

        public static void GUIMinMaxSlider(GUIContent label, SerializedProperty vec2Prop, float a, float b)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 32f);
            rect.height = 16f;
            rect.y += 3f;
            PrefixLabel(rect, label);
            Vector2 vector = vec2Prop.vector2Value;
            rect.y += 13f;
            rect.x += k_ContentLeftMargin;
            rect.width -= k_ContentLeftMargin + k_ContentRightMargin;
            EditorGUI.MinMaxSlider(rect, ref vector.x, ref vector.y, a, b);
            vec2Prop.vector2Value = vector;
        }

        public static void GUIMMColorPopUp(Rect rect, SerializedProperty boolProp)
        {
            if (EditorGUI.ButtonMouseDown(rect, GUIContent.none, FocusType.Passive, ParticleSystemStyles.Get().minMaxCurveStateDropDown))
            {
                GenericMenu menu = new GenericMenu();
                GUIContent[] contentArray = new GUIContent[] { new GUIContent("Constant Color"), new GUIContent("Random Between Two Colors") };
                bool[] flagArray1 = new bool[2];
                flagArray1[1] = true;
                bool[] flagArray = flagArray1;
                for (int i = 0; i < contentArray.Length; i++)
                {
                    menu.AddItem(contentArray[i], boolProp.boolValue == flagArray[i], new GenericMenu.MenuFunction2(ModuleUI.SelectMinMaxColorStateCallback), new ColorCallbackData(flagArray[i], boolProp));
                }
                menu.ShowAsContext();
                Event.current.Use();
            }
        }

        public static void GUIMMCurveStateList(Rect rect, SerializedMinMaxCurve minMaxCurves)
        {
            SerializedMinMaxCurve[] curveArray = new SerializedMinMaxCurve[] { minMaxCurves };
            GUIMMCurveStateList(rect, curveArray);
        }

        public static void GUIMMCurveStateList(Rect rect, SerializedMinMaxCurve[] minMaxCurves)
        {
            if (EditorGUI.ButtonMouseDown(rect, GUIContent.none, FocusType.Passive, ParticleSystemStyles.Get().minMaxCurveStateDropDown) && (minMaxCurves.Length != 0))
            {
                GUIContent[] contentArray = new GUIContent[] { new GUIContent("Constant"), new GUIContent("Curve"), new GUIContent("Random Between Two Constants"), new GUIContent("Random Between Two Curves") };
                MinMaxCurveState[] stateArray1 = new MinMaxCurveState[4];
                stateArray1[1] = MinMaxCurveState.k_Curve;
                stateArray1[2] = MinMaxCurveState.k_TwoScalars;
                stateArray1[3] = MinMaxCurveState.k_TwoCurves;
                MinMaxCurveState[] stateArray = stateArray1;
                bool[] flagArray = new bool[] { minMaxCurves[0].m_AllowConstant, true, minMaxCurves[0].m_AllowRandom, minMaxCurves[0].m_AllowRandom };
                GenericMenu menu = new GenericMenu();
                for (int i = 0; i < contentArray.Length; i++)
                {
                    if (flagArray[i])
                    {
                        menu.AddItem(contentArray[i], minMaxCurves[0].state == stateArray[i], new GenericMenu.MenuFunction2(ModuleUI.SelectMinMaxCurveStateCallback), new CurveStateCallbackData(stateArray[i], minMaxCurves));
                    }
                }
                menu.ShowAsContext();
                Event.current.Use();
            }
        }

        public static void GUIMMGradientPopUp(Rect rect, SerializedMinMaxGradient gradientProp)
        {
            if (EditorGUI.ButtonMouseDown(rect, GUIContent.none, FocusType.Passive, ParticleSystemStyles.Get().minMaxCurveStateDropDown))
            {
                GUIContent[] contentArray = new GUIContent[] { new GUIContent("Color"), new GUIContent("Gradient"), new GUIContent("Random Between Two Colors"), new GUIContent("Random Between Two Gradients") };
                MinMaxGradientState[] stateArray1 = new MinMaxGradientState[4];
                stateArray1[1] = MinMaxGradientState.k_Gradient;
                stateArray1[2] = MinMaxGradientState.k_RandomBetweenTwoColors;
                stateArray1[3] = MinMaxGradientState.k_RandomBetweenTwoGradients;
                MinMaxGradientState[] stateArray = stateArray1;
                bool[] flagArray = new bool[] { gradientProp.m_AllowColor, gradientProp.m_AllowGradient, gradientProp.m_AllowRandomBetweenTwoColors, gradientProp.m_AllowRandomBetweenTwoGradients };
                GenericMenu menu = new GenericMenu();
                for (int i = 0; i < contentArray.Length; i++)
                {
                    if (flagArray[i])
                    {
                        menu.AddItem(contentArray[i], gradientProp.state == stateArray[i], new GenericMenu.MenuFunction2(ModuleUI.SelectMinMaxGradientStateCallback), new GradientCallbackData(stateArray[i], gradientProp));
                    }
                }
                menu.ShowAsContext();
                Event.current.Use();
            }
        }

        public void GUIMMLabel(SerializedProperty boolProp, int type)
        {
            this.GUIMMLabel("   ", boolProp, type);
        }

        public void GUIMMLabel(string name, SerializedProperty boolProp, int type)
        {
            if (boolProp.boolValue)
            {
                GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.ExpandWidth(false) };
                GUILayout.Label(((type != 1) ? string.Empty : "      ") + name + ((type != 0) ? " min" : " max"), options);
                if (type == 1)
                {
                    this.GUIMMSpace();
                }
            }
            else
            {
                GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.ExpandWidth(false) };
                GUILayout.Label(name, optionArray2);
            }
        }

        public void GUIMMSpace()
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(17f) };
            GUILayout.Label(string.Empty, options);
        }

        public static void GUIObject(GUIContent label, SerializedProperty objectProp)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            Rect position = new Rect(rect.x + k_Column1, rect.y + 2f, k_ContentColumn2, rect.height);
            EditorGUI.ObjectReferenceField(position, objectProp, GUIContent.none, ParticleSystemStyles.Get().objectField);
        }

        public static void GUIObjectFieldAndToggle(GUIContent label, SerializedProperty objectProp, SerializedProperty boolProp)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            float width = (k_Column2 - 12f) - 10f;
            Rect position = new Rect(rect.x + k_Column1, rect.y, width, rect.height);
            EditorGUI.ObjectReferenceField(position, objectProp, GUIContent.none);
            if (boolProp != null)
            {
                position.x = ((rect.x + k_ModuleWidth) - 12f) - k_ContentRightMargin;
                position.width = 12f;
                Toggle(position, boolProp);
            }
        }

        public static int GUIPopup(string name, SerializedProperty intProp, string[] options)
        {
            return GUIPopup(GUIContent.Temp(name), intProp, options);
        }

        public static int GUIPopup(GUIContent label, int intValue, string[] options)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            rect.x += k_Column1;
            rect.width = k_ContentColumn2;
            return EditorGUI.Popup(rect, intValue, options, ParticleSystemStyles.Get().popup);
        }

        public static int GUIPopup(GUIContent label, SerializedProperty intProp, string[] options)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, label);
            rect.x += k_Column1;
            rect.width = k_ContentColumn2;
            intProp.intValue = EditorGUI.Popup(rect, intProp.intValue, options, ParticleSystemStyles.Get().popup);
            return intProp.intValue;
        }

        public static void GUISlider(SerializedProperty floatProp, float a, float b, float remap)
        {
            GUISlider(string.Empty, floatProp, a, b, remap);
        }

        public static void GUISlider(string name, SerializedProperty floatProp, float a, float b, float remap)
        {
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.MinWidth(300f) };
            floatProp.floatValue = EditorGUILayout.Slider(name, floatProp.floatValue * remap, a, b, options) / remap;
        }

        public static bool GUIToggle(string label, SerializedProperty boolProp)
        {
            return GUIToggle(GUIContent.Temp(label), boolProp);
        }

        public static bool GUIToggle(GUIContent guiContent, bool boolValue)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            Rect position = new Rect(rect.x + k_Column1, rect.y + 2f, 12f, 12f);
            boolValue = GUI.Toggle(position, boolValue, GUIContent.none, ParticleSystemStyles.Get().toggle);
            SpaceToNextLine();
            return boolValue;
        }

        public static bool GUIToggle(GUIContent guiContent, SerializedProperty boolProp)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            Rect rect2 = new Rect(rect.x + k_Column1, rect.y + 2f, 12f, 12f);
            bool flag = Toggle(rect2, boolProp);
            SpaceToNextLine();
            return flag;
        }

        public static void GUIToggleWithFloatField(string name, SerializedProperty boolProp, SerializedProperty floatProp)
        {
            GUIToggleWithFloatField(EditorGUIUtility.TempContent(name), boolProp, floatProp);
        }

        public static void GUIToggleWithFloatField(GUIContent guiContent, SerializedProperty boolProp, SerializedProperty floatProp)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            Rect rect2 = new Rect(rect.x + k_Column1, rect.y + 2f, 12f, 12f);
            if (Toggle(rect2, boolProp))
            {
                float dragWidth = 25f;
                float floatFieldWidth = (k_Column2 - 12f) - dragWidth;
                Rect rect3 = new Rect((rect.x + k_Column1) + 12f, rect.y, k_Column2 - 12f, rect.height);
                FloatDraggable(rect3, floatProp, 1f, dragWidth, floatFieldWidth);
            }
            SpaceToNextLine();
        }

        public static void GUIToogleWithIntField(string name, SerializedProperty boolProp, SerializedProperty floatProp, bool invertToggle)
        {
            GUIToogleWithIntField(EditorGUIUtility.TempContent(name), boolProp, floatProp, invertToggle);
        }

        public static void GUIToogleWithIntField(GUIContent guiContent, SerializedProperty boolProp, SerializedProperty intProp, bool invertToggle)
        {
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f);
            PrefixLabel(rect, guiContent);
            Rect rect2 = new Rect(rect.x + k_Column1, rect.y + 2f, 12f, 12f);
            bool flag = Toggle(rect2, boolProp);
            if (!invertToggle ? flag : !flag)
            {
                float dragWidth = 25f;
                float intFieldWidth = (k_Column2 - 12f) - dragWidth;
                Rect rect3 = new Rect((rect.x + k_Column1) + 12f, rect.y, k_Column2 - 12f, rect.height);
                intProp.intValue = IntDraggable(rect3, null, intProp.intValue, dragWidth, intFieldWidth);
            }
            SpaceToNextLine();
        }

        public void GUITripleMinMaxCurve(GUIContent label, GUIContent x, SerializedMinMaxCurve xCurve, GUIContent y, SerializedMinMaxCurve yCurve, GUIContent z, SerializedMinMaxCurve zCurve, SerializedProperty randomizePerFrame)
        {
            MinMaxCurveState state = xCurve.state;
            bool flag = label != GUIContent.none;
            int num = !flag ? 1 : 2;
            if (state == MinMaxCurveState.k_TwoScalars)
            {
                num++;
            }
            Rect rect = GUILayoutUtility.GetRect(k_ModuleWidth, 16f * num);
            Rect rect2 = rect;
            float num2 = 10f;
            float num3 = 8f;
            float num4 = (((k_ModuleWidth - num2) - 8f) - (3f * num3)) / 3f;
            float dragWidth = 11f;
            float floatFieldWidth = num4 - dragWidth;
            if (num > 1)
            {
                rect2.height = 16f;
            }
            if (flag)
            {
                PrefixLabel(rect, label);
                rect2.y += rect2.height;
            }
            rect2.x += num2;
            rect2.width = num4;
            GUIContent[] contentArray = new GUIContent[] { x, y, z };
            SerializedMinMaxCurve[] minMaxCurves = new SerializedMinMaxCurve[] { xCurve, yCurve, zCurve };
            switch (state)
            {
                case MinMaxCurveState.k_Scalar:
                    for (int i = 0; i < minMaxCurves.Length; i++)
                    {
                        Label(rect2, contentArray[i]);
                        float a = FloatDraggable(rect2, minMaxCurves[i].scalar, minMaxCurves[i].m_RemapValue, dragWidth, floatFieldWidth);
                        if (!minMaxCurves[i].signedRange)
                        {
                            minMaxCurves[i].scalar.floatValue = Mathf.Max(a, 0f);
                        }
                        rect2.x += num4 + num3;
                    }
                    break;

                case MinMaxCurveState.k_TwoScalars:
                    for (int j = 0; j < minMaxCurves.Length; j++)
                    {
                        Label(rect2, contentArray[j]);
                        float minConstant = minMaxCurves[j].minConstant;
                        float maxConstant = minMaxCurves[j].maxConstant;
                        EditorGUI.BeginChangeCheck();
                        maxConstant = FloatDraggable(rect2, maxConstant, minMaxCurves[j].m_RemapValue, dragWidth, floatFieldWidth, "g5");
                        if (EditorGUI.EndChangeCheck())
                        {
                            minMaxCurves[j].maxConstant = maxConstant;
                        }
                        rect2.y += 16f;
                        EditorGUI.BeginChangeCheck();
                        minConstant = FloatDraggable(rect2, minConstant, minMaxCurves[j].m_RemapValue, dragWidth, floatFieldWidth, "g5");
                        if (EditorGUI.EndChangeCheck())
                        {
                            minMaxCurves[j].minConstant = minConstant;
                        }
                        rect2.x += num4 + num3;
                        rect2.y -= 16f;
                    }
                    break;

                default:
                {
                    rect2.width = floatFieldWidth;
                    float height = rect2.height;
                    Rect ranges = !xCurve.signedRange ? kUnsignedRange : kSignedRange;
                    for (int k = 0; k < minMaxCurves.Length; k++)
                    {
                        Label(rect2, contentArray[k]);
                        rect2.x += dragWidth;
                        rect2.height = 13f;
                        SerializedProperty minCurve = (state != MinMaxCurveState.k_TwoCurves) ? null : minMaxCurves[k].minCurve;
                        GUICurveField(rect2, minMaxCurves[k].maxCurve, minCurve, GetColor(minMaxCurves[k]), ranges, new CurveFieldMouseDownCallback(minMaxCurves[k].OnCurveAreaMouseDown));
                        rect2.height = height;
                        rect2.x += rect2.width + num3;
                    }
                    break;
                }
            }
            Rect rect4 = new Rect(((rect.x + k_ModuleWidth) - 12f) - k_ContentRightMargin, rect2.y, 12f, rect.height);
            GUIMMCurveStateList(rect4, minMaxCurves);
            SpaceToNextLine();
        }

        public static void GUIVector3(SerializedProperty vec3Prop)
        {
            Vector3 vector = vec3Prop.vector3Value;
            EditorGUIUtility.LookLikeControls();
            GUILayout.Label("X", new GUILayoutOption[0]);
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.x = EditorGUILayout.FloatField(vector.x, options);
            GUILayout.Label("Y", new GUILayoutOption[0]);
            GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.y = EditorGUILayout.FloatField(vector.y, optionArray2);
            GUILayout.Label("Z", new GUILayoutOption[0]);
            GUILayoutOption[] optionArray3 = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.z = EditorGUILayout.FloatField(vector.z, optionArray3);
            vec3Prop.vector3Value = vector;
            EditorGUIUtility.LookLikeInspector();
        }

        public static void GUIVector3(SerializedProperty xProp, SerializedProperty yProp, SerializedProperty zProp)
        {
            Vector3 vector = new Vector3(xProp.floatValue, yProp.floatValue, zProp.floatValue);
            EditorGUIUtility.LookLikeControls();
            GUILayout.Label("X", new GUILayoutOption[0]);
            GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.x = EditorGUILayout.FloatField(vector.x, options);
            GUILayout.Label("Y", new GUILayoutOption[0]);
            GUILayoutOption[] optionArray2 = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.y = EditorGUILayout.FloatField(vector.y, optionArray2);
            GUILayout.Label("Z", new GUILayoutOption[0]);
            GUILayoutOption[] optionArray3 = new GUILayoutOption[] { GUILayout.Width(23f) };
            vector.z = EditorGUILayout.FloatField(vector.z, optionArray3);
            xProp.floatValue = vector.x;
            yProp.floatValue = vector.y;
            zProp.floatValue = vector.z;
            EditorGUIUtility.LookLikeInspector();
        }

        protected abstract void Init();
        public static int IntDraggable(Rect rect, GUIContent label, int value, float dragWidth, float intFieldWidth)
        {
            float num = dragWidth + intFieldWidth;
            Rect position = rect;
            position.width = num;
            int id = EditorGUI.GetControlID(0xfd15f8, FocusType.Keyboard, position);
            Rect rect3 = position;
            rect3.width = dragWidth;
            if ((label != null) && !string.IsNullOrEmpty(label.text))
            {
                Label(rect3, label);
            }
            Rect rect4 = position;
            rect4.x += dragWidth;
            rect4.width = intFieldWidth;
            float dragSensitivity = Mathf.Max((float) 1f, (float) (Mathf.Pow(Mathf.Abs((float) value), 0.5f) * 0.03f));
            return (int) EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, rect4, rect3, id, (float) value, EditorGUI.kIntFieldFormatString, ParticleSystemStyles.Get().numberField, true, dragSensitivity);
        }

        public static int IntDraggable(Rect rect, GUIContent label, SerializedProperty intProp, float dragWidth, float intFieldWidth)
        {
            intProp.intValue = IntDraggable(rect, label, intProp.intValue, dragWidth, intFieldWidth);
            return intProp.intValue;
        }

        private static void Label(Rect rect, GUIContent guiContent)
        {
            GUI.Label(rect, guiContent, ParticleSystemStyles.Get().label);
        }

        public abstract void OnInspectorGUI(ParticleSystem s);
        protected virtual void OnModuleDisable()
        {
            ParticleSystemCurveEditor particleSystemCurveEditor = this.m_ParticleSystemUI.m_ParticleEffectUI.GetParticleSystemCurveEditor();
            foreach (SerializedProperty property in this.m_ModuleCurves)
            {
                if (particleSystemCurveEditor.IsAdded(property))
                {
                    particleSystemCurveEditor.RemoveCurve(property);
                }
            }
        }

        protected virtual void OnModuleEnable()
        {
            this.Init();
        }

        public virtual void OnSceneGUI(ParticleSystem s, InitialModuleUI initial)
        {
        }

        internal UnityEngine.Object ParticleSystemValidator(UnityEngine.Object[] references, System.Type objType, SerializedProperty property)
        {
            foreach (UnityEngine.Object obj2 in references)
            {
                if (obj2 != null)
                {
                    GameObject obj3 = obj2 as GameObject;
                    if (obj3 != null)
                    {
                        ParticleSystem component = obj3.GetComponent<ParticleSystem>();
                        if (component != null)
                        {
                            return component;
                        }
                    }
                }
            }
            return null;
        }

        private static void PrefixLabel(Rect rect, GUIContent guiContent)
        {
            rect.x += k_ContentLeftMargin;
            rect.width = k_Column1;
            GUI.Label(rect, guiContent, ParticleSystemStyles.Get().label);
        }

        private static void SelectMinMaxColorStateCallback(object obj)
        {
            ColorCallbackData data = (ColorCallbackData) obj;
            data.boolProp.boolValue = data.selectedState;
        }

        private static void SelectMinMaxCurveStateCallback(object obj)
        {
            CurveStateCallbackData data = (CurveStateCallbackData) obj;
            foreach (SerializedMinMaxCurve curve in data.minMaxCurves)
            {
                curve.state = data.selectedState;
            }
        }

        private static void SelectMinMaxGradientStateCallback(object obj)
        {
            GradientCallbackData data = (GradientCallbackData) obj;
            data.gradientProp.state = data.selectedState;
        }

        public static void SetModuleRulers(float column1Width, float column2Width)
        {
            k_Column1 = column1Width;
            k_Column2 = column2Width;
            k_ContentColumn2 = k_Column2 - k_ContentRightMargin;
            k_ModuleWidth = k_Column1 + k_Column2;
        }

        private void Setup(ParticleSystemUI owner, SerializedObject o, string name, string displayName, VisibilityState defaultVisibilityState)
        {
            this.m_ParticleSystemUI = owner;
            this.m_DisplayName = displayName;
            if (this is RendererModuleUI)
            {
                this.m_Enabled = base.GetProperty0("m_Enabled");
            }
            else
            {
                this.m_Enabled = base.GetProperty("enabled");
            }
            this.m_VisibilityState = (VisibilityState) InspectorState.GetInt(base.GetUniqueModuleName(), (int) defaultVisibilityState);
            this.CheckVisibilityState();
            if (this.foldout)
            {
                this.Init();
            }
        }

        protected virtual void SetVisibilityState(VisibilityState newState)
        {
            if (newState != this.m_VisibilityState)
            {
                if (newState == VisibilityState.VisibleAndFolded)
                {
                    ParticleSystemCurveEditor particleSystemCurveEditor = this.m_ParticleSystemUI.m_ParticleEffectUI.GetParticleSystemCurveEditor();
                    foreach (SerializedProperty property in this.m_ModuleCurves)
                    {
                        if (particleSystemCurveEditor.IsAdded(property))
                        {
                            this.m_CurvesRemovedWhenFolded.Add(property);
                            particleSystemCurveEditor.SetVisible(property, false);
                        }
                    }
                    particleSystemCurveEditor.Refresh();
                }
                else if (newState == VisibilityState.VisibleAndFoldedOut)
                {
                    ParticleSystemCurveEditor editor2 = this.m_ParticleSystemUI.m_ParticleEffectUI.GetParticleSystemCurveEditor();
                    foreach (SerializedProperty property2 in this.m_CurvesRemovedWhenFolded)
                    {
                        editor2.SetVisible(property2, true);
                    }
                    this.m_CurvesRemovedWhenFolded.Clear();
                    editor2.Refresh();
                }
                this.m_VisibilityState = newState;
                InspectorState.SetInt(base.GetUniqueModuleName(), (int) this.m_VisibilityState);
                if (newState == VisibilityState.VisibleAndFoldedOut)
                {
                    this.Init();
                }
            }
        }

        private static void SpaceToNextLine()
        {
        }

        private static bool Toggle(Rect rect, SerializedProperty boolProp)
        {
            bool boolValue = boolProp.boolValue;
            bool flag2 = GUI.Toggle(rect, boolValue, GUIContent.none, ParticleSystemStyles.Get().toggle);
            if (boolValue != flag2)
            {
                boolProp.boolValue = flag2;
            }
            return flag2;
        }

        public virtual void UpdateCullingSupportedString(ref string text)
        {
        }

        public virtual void Validate()
        {
        }

        public string displayName
        {
            get
            {
                return this.m_DisplayName;
            }
        }

        public bool enabled
        {
            get
            {
                return this.m_Enabled.boolValue;
            }
            set
            {
                if (this.m_Enabled.boolValue != value)
                {
                    this.m_Enabled.boolValue = value;
                    if (value)
                    {
                        this.OnModuleEnable();
                    }
                    else
                    {
                        this.OnModuleDisable();
                    }
                }
            }
        }

        public bool foldout
        {
            get
            {
                return (this.m_VisibilityState == VisibilityState.VisibleAndFoldedOut);
            }
            set
            {
                this.SetVisibilityState(!value ? VisibilityState.VisibleAndFolded : VisibilityState.VisibleAndFoldedOut);
            }
        }

        public string toolTip
        {
            get
            {
                return this.m_ToolTip;
            }
        }

        public bool visibleUI
        {
            get
            {
                return (this.m_VisibilityState != VisibilityState.NotVisible);
            }
            set
            {
                this.SetVisibilityState(!value ? VisibilityState.NotVisible : VisibilityState.VisibleAndFolded);
            }
        }

        private class ColorCallbackData
        {
            public SerializedProperty boolProp;
            public bool selectedState;

            public ColorCallbackData(bool state, SerializedProperty bp)
            {
                this.boolProp = bp;
                this.selectedState = state;
            }
        }

        public delegate bool CurveFieldMouseDownCallback(int button, Rect drawRect, Rect curveRanges);

        private class CurveStateCallbackData
        {
            public SerializedMinMaxCurve[] minMaxCurves;
            public MinMaxCurveState selectedState;

            public CurveStateCallbackData(MinMaxCurveState state, SerializedMinMaxCurve[] curves)
            {
                this.minMaxCurves = curves;
                this.selectedState = state;
            }
        }

        private class GradientCallbackData
        {
            public SerializedMinMaxGradient gradientProp;
            public MinMaxGradientState selectedState;

            public GradientCallbackData(MinMaxGradientState state, SerializedMinMaxGradient p)
            {
                this.gradientProp = p;
                this.selectedState = state;
            }
        }

        public enum VisibilityState
        {
            NotVisible,
            VisibleAndFolded,
            VisibleAndFoldedOut
        }
    }
}

